function NotNumber(target: any, propertyKey: string, parameterIndex: number) {
  // console.log(typeof target)
  // console.log(target[`__notNumber_${propertyKey}`])
  // 初始化或获取当前方法的参数索引列表
  console.log(Object.getOwnPropertyDescriptor(target, `__notNumber_${propertyKey}`))
  let notNumberArr: number[] = target[`__notNumber_${propertyKey}`] || []
  // let notNumberArr: number[] = Object.getOwnPropertyDescriptor(target, `__notNumber_${propertyKey}`)?.value || []

  // 将当前参数索引添加到列表中
  notNumberArr.push(parameterIndex)

  // 将列表存储回目标对象
  target[`__notNumber_${propertyKey}`] = notNumberArr
  // Object.defineProperty(target, `__notNumber_${propertyKey}`, { value: notNumberArr })
  // console.log(target[`__notNumber_${propertyKey}`])
}

// 方法装饰器定义
function Validate(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
  const method = descriptor.value
  descriptor.value = function (...args: any[]) {
    // 获取被标记为不能为 number 的参数索引列表
    const notNumberArr: number[] = target[`__notNumber_${propertyKey}`] || []
    // 检查番薯是否为 number 
    for (const index of notNumberArr) {
      if (typeof args[index] === 'number') {
        throw new Error(`方法 ${propertyKey} 中索引为 ${index} 的参数不能是数字！`)
      }
    }
    // 调用原始方法
    return method.apply(this, args)
  }
  return descriptor;
}

// 定义类
class Student {
  constructor(public name: string) { }

  @Validate
  speak(/* @NotNumber */ massage1: any, /* @NotNumber */ message2: any) {
    console.log(`${this.name} 想说: ${massage1}, ${message2}`)
  }

  @Validate
  static logInfo(@NotNumber value1: any, @NotNumber value2: any) {
    console.log(value1, value2)
  }
}
// 使用
const s1 = new Student('tom')
console.log(s1)
console.log(Student)
s1.speak(100, 200)
Student.logInfo(100, 200)
